﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using netDxf;
using netDxf.Entities;
using System.Drawing;
using OpenTK.Graphics.OpenGL;

unsafe public class CapaDXF : IEntidad
{
    Linea[] arrLineas;
    public CapaDXF(string _strRuta, int _intTamano, string strIDCapa,  Escenario pEscena, Colores objColor, float intEntidadAlto, float intEntidadLargo, Colores objColorTextos)
    {
        this.ID = strIDCapa;
            arrLineas = new Linea[_intTamano];
        for (int i = 0; i < _intTamano; i++)
        {
            arrLineas[i] = new Linea();
        }
        this.Visible = true;
        this.Coloreado = objColor;
        this.ColoreadoTextos = objColorTextos;
        this.Escena = pEscena;
        this.EntidadAlto = intEntidadAlto;
        this.EntidadLargo = intEntidadLargo;
        this.Documento=new DxfDocument();
        this.Documento.Load(_strRuta);
        generar();
    }

    private DxfDocument _Documento;
    public DxfDocument Documento
    {
        get { return _Documento; }
        set { _Documento = value; }
    }

    private Escenario _Escena;
    public Escenario Escena
    {
        get { return _Escena; }
        set { _Escena = value; }
    }

    private string _tabla;
    public string Tabla
    {
        get { return _tabla; }
        set { _tabla = value; }
    }

    float _EntidadAlto;
    public float EntidadAlto
    {
        get { return _EntidadAlto; }
        set { _EntidadAlto = value; }
    }

    float _EntidadLargo;
    public float EntidadLargo
    {
        get { return _EntidadLargo; }
        set { _EntidadLargo = value; }
    }

    private int _IndiceActual;
    public int IndiceActual
    {
        get { return _IndiceActual; }
        set { _IndiceActual = value; }
    }

    private string SQL;
    public string SQL1
    {
        get { return SQL; }
        set { SQL = value; }
    }

    private int _TamanoMax;
    public int TamanoMax
    {
        get { return _TamanoMax; }
        set { _TamanoMax = value; }
    }

    private string _id;
    public string ID
    {
        get { return _id; }
        set { _id = value; }
    }

    public Capa CapaCanvas
    {
        get { return null; }
        set { }
    }

    private Colores _coloreadoBorde;
    public Colores ColoreadoBorde
    {
        get { return _coloreadoBorde; }
        set { _coloreadoBorde = value; }
    }

    private Colores _ColoreadoTextos;
    public Colores ColoreadoTextos
    {
        get { return _ColoreadoTextos; }
        set { _ColoreadoTextos = value; }
    }

    
    private Estilo.Borde _tipoBorde;
    public Estilo.Borde TipoBorde
    {
        get { return this._tipoBorde; }
        set { this._tipoBorde = value; }
    }

    private int _alturaMax = 0;
    public int AlturaMax
    {
        get { return _alturaMax; }
        set { _alturaMax = value; }
    }

    private short _largo = 0;
    public short Largo
    {
        get { return _largo; }
        set { _largo = value; }
    }

    private float _alto = 0;
    public float Alto
    {
        get { return _alto; }
        set { _alto = value; }
    }

    private Colores _coloreado;
    public Colores Coloreado
    {
        get { return _coloreado; }
        set { _coloreado = value; }
    }

    private float _grosor;
    public float Grosor
    {
        get { return _grosor; }
        set { _grosor = value; }
    }

    private float _radio;
    public float Radio
    {
        get { return _radio; }
        set { _radio = value; }
    }

    private bool _visible;
    public bool Visible
    {
        get { return this._visible; }
        set { this._visible = value; }
    }

    private Estilo.Forma _tipoForma;
    public Estilo.Forma TipoForma
    {
        get { return this._tipoForma; }
        set { this._tipoForma = value; }
    }

    private TIPO_ENTIDAD _objEntidad;
    public TIPO_ENTIDAD TipoEntidad
    {
        get { return this._objEntidad; }
    }

    private TIPO_CAPA_SQL _TipoCapaSQL;
    public TIPO_CAPA_SQL TipoCapaSQL
    {
        get { return this._TipoCapaSQL; }
    }


    private Coordenada _localizacion;
    public Coordenada Localizacion
    {
        get { return _localizacion; }
        set
        {
            _localizacion = value;
        }
    }

    bool blnCompilada = false;
    public unsafe void _pintar()
    {
        //Tamano de la lineas y colores
        if (this.Coloreado != null)
        {
            GL.Color4(this.Coloreado.Rojo, this.Coloreado.Verde, this.Coloreado.Azul, this.Coloreado.Alfa);
        }
        GL.LineWidth(this.EntidadLargo);

        if (!blnCompilada)
        {
            compilar();
        }
        GL.CallList(_indice);
    }

    int _indice;
    public unsafe void compilar()
    { 
        _indice = GL.GenLists(1);
        GL.NewList(_indice, ListMode.Compile);
        /*if (this.Coloreado!=null) 
        {
                GL.Color4(Coloreado.Rojo, Coloreado.Verde, Coloreado.Azul, Coloreado.Alfa);
        }*/
        //GL.LineWidth(this._EntidadLargo);
        for (int i = 0; i <= IndiceActual; i++)
        {
            arrLineas[i]._pintar();
        }
        GL.EndList();
        blnCompilada = true;
    }


    int intConsecutivoLinea=0;
    private unsafe void generar()
    {
        Color objColor;
        Colores objColorLinea=null;
        float x, y, x2, y2;
        foreach (netDxf.Entities.Line objLinea in Documento.Lines)
        {
            objColor=objLinea.Color.ToColor();
            IndiceActual++;
            x = objLinea.StartPoint.X;
            y = objLinea.StartPoint.Y;
            x2 = objLinea.EndPoint.X;
            y2 = objLinea.EndPoint.Y;
            if (this.Coloreado == null)
            {
                objColorLinea = new Colores(objColor);
                arrLineas[IndiceActual].Coloreado = objColorLinea;
            }
            else
            {
                arrLineas[IndiceActual].Coloreado = this.Coloreado;
            }
            arrLineas[IndiceActual].Localizacion = new Coordenada(x, y, this.Alto);
            arrLineas[IndiceActual].Localizacion2 = new Coordenada(x2, y2, this.Alto);
            arrLineas[IndiceActual].ID = (intConsecutivoLinea++).ToString();
        }

        //this.ColoreadoTextos
        FuenteStroke objFuente;
        foreach (netDxf.Entities.Text objTexto in Documento.Texts)
        {
            intConsecutivoLinea++;
            objFuente= new FuenteStroke(intConsecutivoLinea.ToString(), new Coordenada(objTexto.BasePoint.X, objTexto.BasePoint.Y), 1, 1);
            objFuente.Visible = true;
            objFuente.Grosor = 1;
            objFuente.Coloreado = ColoreadoTextos;
            objFuente.Cadena = objTexto.Value.Replace("'", "");
            objFuente.Rotacion = ushort.Parse(Math.Ceiling((Decimal)objTexto.Rotation).ToString());
            this.Escena.adicionar(objFuente);
            /*Conexion.Ejecutar("INSERT INTO DTE_DXF_TEXTO(DTE_CAPA, DTE_R, DTE_G, DTE_B, DTE_X, DTE_Y, DTE_ROTACION, DTE_TEXTO)" +
                                                    "VALUES('" + objTexto.Layer + "', " + objColor.R / 255 + ", " + objColor.G / 255 + "," +
                                                    objColor.B / 255 + "," + objTexto.BasePoint.X.ToString().Replace(",", ".") + ", " + objTexto.BasePoint.Y.ToString().Replace(",", ".") + "," +
                                                    objTexto.Rotation.ToString().Replace(",", ".") + ", '" + objTexto.Value.Replace("'", "") + "')");*/
        }
        foreach (netDxf.Entities.IPolyline objPolilinea in Documento.Polylines)
        {
            if (objPolilinea.Type == netDxf.Entities.EntityType.LightWeightPolyline)
            {
                DibujarPoliLineaSuave((netDxf.Entities.LightWeightPolyline)objPolilinea);
            }
            else if (objPolilinea.Type == netDxf.Entities.EntityType.Polyline3d)
            {
                DibujarPoliLinea3D((netDxf.Entities.Polyline3d)objPolilinea);
            }
            else
            {
                DibujarPoliLinea((netDxf.Entities.Polyline)objPolilinea);
            }
        }
    }

    private unsafe void DibujarPoliLinea(netDxf.Entities.Polyline objPolilinea)
    {
        Color objColor;
        Colores objColorLinea = null;
        netDxf.Entities.PolylineVertex objPunto1 = null;
        netDxf.Entities.PolylineVertex objPunto2 = null;
        float x, y, x2, y2;
        for (int i = 0; i < objPolilinea.Vertexes.Count; i++)
        {
            objPunto1 = objPolilinea.Vertexes[i];
            objColor = objPolilinea.Color.ToColor();
            IndiceActual++;
            if (this.Coloreado == null)
            {
                objColorLinea = new Colores(objColor);
                arrLineas[IndiceActual].Coloreado = objColorLinea;
            }
            else
            {
                arrLineas[IndiceActual].Coloreado = this.Coloreado;
            }
            if (i < (objPolilinea.Vertexes.Count - 1))
            {
                objPunto2 = objPolilinea.Vertexes[i + 1];
            }
            if (objPolilinea.IsClosed && (objPolilinea.Vertexes.Count - 1) == i)
            {
                objPunto1 = objPolilinea.Vertexes[0];
                objPunto2 = objPolilinea.Vertexes[i];
            }
            x = objPunto1.Location.X;
            y = objPunto1.Location.Y;
            x2 = objPunto2.Location.X;
            y2 = objPunto2.Location.Y;
            arrLineas[IndiceActual].Localizacion = new Coordenada(x, y, this.Alto);
            arrLineas[IndiceActual].Localizacion2 = new Coordenada(x2, y2, this.Alto);
            arrLineas[IndiceActual].ID = (intConsecutivoLinea++).ToString();
        }



    }

    private unsafe void DibujarPoliLinea3D(netDxf.Entities.Polyline3d objPolilinea)
    {
        Color objColor;
        netDxf.Entities.Polyline3dVertex objPunto1 = null;
        netDxf.Entities.Polyline3dVertex objPunto2 = null;
        Colores objColorLinea = null;
        float x, y, x2, y2;
        for (int i = 0; i < objPolilinea.Vertexes.Count; i++)
        {
            IndiceActual++;
            objPunto1 = objPolilinea.Vertexes[i];
            objColor = objPolilinea.Color.ToColor();
            if (this.Coloreado == null)
            {
                objColorLinea = new Colores(objColor);
                arrLineas[IndiceActual].Coloreado = objColorLinea;
            }
            else
            {
                arrLineas[IndiceActual].Coloreado = this.Coloreado;
            }
            if (i < (objPolilinea.Vertexes.Count - 1))
            {
                objPunto2 = objPolilinea.Vertexes[i + 1];
                x = objPunto1.Location.X;
                y = objPunto1.Location.Y;
                x2 = objPunto2.Location.X;
                y2 = objPunto2.Location.Y;
                arrLineas[IndiceActual].Localizacion = new Coordenada(x, y, this.Alto);
                arrLineas[IndiceActual].Localizacion2 = new Coordenada(x2, y2, this.Alto);
                arrLineas[IndiceActual].ID = (intConsecutivoLinea++).ToString();
            }
        }
    }

    private unsafe void DibujarPoliLineaSuave(netDxf.Entities.LightWeightPolyline objPolilinea)
    {
        Color objColor;
        netDxf.Entities.LightWeightPolylineVertex objPunto1 = null;
        netDxf.Entities.LightWeightPolylineVertex objPunto2 = null;
        Colores objColorLinea = null;
        float x, y, x2, y2;
        for (int i = 0; i < objPolilinea.Vertexes.Count; i++)
        {
            IndiceActual++;
            objColor = objPolilinea.Color.ToColor();
            if (this.Coloreado == null)
            {
                objColorLinea = new Colores(objColor);
                arrLineas[IndiceActual].Coloreado = objColorLinea;
            }
            else
            {
                arrLineas[IndiceActual].Coloreado = this.Coloreado;
            }
            objPunto1 = objPolilinea.Vertexes[i];
            if (i < (objPolilinea.Vertexes.Count - 1))
            {
                objPunto2 = objPolilinea.Vertexes[i + 1];
            }
            if (objPolilinea.IsClosed && (objPolilinea.Vertexes.Count - 1) == i)
            {
                objPunto1 = objPolilinea.Vertexes[0];
                objPunto2 = objPolilinea.Vertexes[i];
            }
            x = objPunto1.Location.X;
            y = objPunto1.Location.Y;
            x2 = objPunto2.Location.X;
            y2 = objPunto2.Location.Y;
            arrLineas[IndiceActual].Localizacion = new Coordenada(x, y, this.Alto);
            arrLineas[IndiceActual].Localizacion2 = new Coordenada(x2, y2, this.Alto);
            arrLineas[IndiceActual].ID = (intConsecutivoLinea++).ToString();
        }
    }
}
